package com.tianyu.inspection.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.itextpdf.xmp.impl.Base64;
import com.tianyu.inspection.common.Constants;
import com.tianyu.inspection.common.enums.FileTypeEnum;
import com.tianyu.inspection.common.enums.RoState;
import com.tianyu.inspection.common.enums.Role;
import com.tianyu.inspection.common.model.NetworkModel;
import com.tianyu.inspection.common.model.PhoneModel;
import com.tianyu.inspection.common.annotation.Permission;
import com.tianyu.inspection.common.component.Validate;
import com.tianyu.inspection.entity.User;
import com.tianyu.inspection.entity.model.OperateMo;
import com.tianyu.inspection.entity.model.QueryMo;
import com.tianyu.inspection.entity.vo.Ro;
import com.tianyu.inspection.entity.vo.ServiceRo;
import com.tianyu.inspection.service.api.IUserService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Objects;

/**********************************
 * @Author YSW
 * @Description 用户登录接口
 * @Date 2021/1/7 - 11:48
 **********************************/

@RestController
@RequestMapping("/api/2.0/user")
public class UserController {

    @Resource
    private IUserService userService;

    @Resource
    private Validate validateModel;

    @PostMapping(value = "/login")
    @Permission(value = 4, tags = Constants.API_PATROL)
    private Ro<User> login(@RequestBody QueryMo queryMo, HttpServletRequest httpServletRequest) {
        User user = new User().setAccount((String) queryMo.get("account"))
                .setPassword((String) queryMo.get("password"));
        Ro<User> ro = new Ro<>();
        if (Objects.isNull(user.getAccount())) {
            ro.setResultEnum(RoState.FAIL);
            ro.setMessage("账号(手机号/用户名)不能为空");
            return ro;
        } else {
            user.setPhone(user.getAccount());
            user.setUserName(user.getAccount());
        }
        if (Objects.isNull(user.getPassword())) {
            ro.setResultEnum(RoState.FAIL);
            ro.setMessage("密码不能为空");
            return ro;
        }
        try {
            String ip = NetworkModel.getIpAddress(httpServletRequest);
            user.setLastIp(ip);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return userService.login(user);
    }

    @PostMapping(value = "/logout")
    @Permission(value = 3, tags = Constants.API_COMPANY)
    public Ro<Void> logout(@RequestHeader("u-uid") Integer uid, @RequestHeader("u-token") String token) {
        return userService.logout(uid, token);
    }

    @PostMapping(value = "/state")
    @Permission(value = 4, tags = Constants.API_PATROL)
    public Ro<Object> state() {
        return new Ro<>().setMessage("用户在线");
    }

    @Permission(value = 3, tags = Constants.API_COMPANY)
    @GetMapping(value = "/inspectors")
    public Ro<Object> inspectors(@RequestHeader("u-projectId") Integer projectId, HttpServletRequest request) {
        int roleId = (int) request.getAttribute("roleId");
        Ro<Object> ro = new Ro<>();
        if (roleId == Role.ROLE_COMPANY_ADMIN.getValue() || roleId == Role.ROLE_COMPANY_COMMON.getValue()) {
            QueryMo queryMo = new QueryMo();
            queryMo.put("roleId", Role.ROLE_PATROL.getValue());
            queryMo.build(User.class, projectId);
            IPage<User> userPage = userService.searchListPage(queryMo);
            if (userPage.getRecords().isEmpty()) {
                return ro.setResultEnum(RoState.FAIL).setMessage("暂无巡线员!");
            }
            userPage.getRecords().forEach(user -> {
                user.setRoleId(null);
                user.setUserName(null);
                user.setAddress(null);
                user.setAvatarUrl(null);
                user.setState(null);
                user.setPassword(null);
                user.setToken(null);
                user.setLastTime(null);
                user.setLastIp(null);
            });
            return ro.setContent(userPage.getRecords());
        } else {
            return ro.setResultEnum(RoState.FAIL).setMessage("非企业管理员用户或企业普通用户不可用!");
        }
    }

    @Permission(value = 3, tags = Constants.API_COMPANY)
    @GetMapping(value = "/pilots")
    public Ro<Object> pilots(@RequestHeader("u-projectId") Integer projectId, HttpServletRequest request) {
        int roleId = (int) request.getAttribute("roleId");
        Ro<Object> ro = new Ro<>();
        if (roleId == Role.ROLE_COMPANY_ADMIN.getValue() || roleId == Role.ROLE_COMPANY_COMMON.getValue()) {
            QueryMo queryMo = new QueryMo();
            queryMo.put("roleId", Role.ROLE_UAV_CONTROL.getValue());
            queryMo.build(User.class, projectId);
            IPage<User> userPage = userService.searchListPage(queryMo);
            if (userPage.getRecords().isEmpty()) {
                return ro.setResultEnum(RoState.FAIL).setMessage("暂无巡线员!");
            }
            userPage.getRecords().forEach(user -> {
                user.setRoleId(null);
                user.setUserName(null);
                user.setAddress(null);
                user.setAvatarUrl(null);
                user.setState(null);
                user.setPassword(null);
                user.setToken(null);
                user.setLastTime(null);
                user.setLastIp(null);
            });
            return ro.setContent(userPage.getRecords());
        } else {
            return ro.setResultEnum(RoState.FAIL).setMessage("非企业管理员用户或企业普通用户不可用!");
        }
    }

    @PostMapping(value = "/register")
    @Permission(value = 2, tags = Constants.API_ADMIN)
    public Ro<User> insert(@RequestBody OperateMo operateMo,
                           @RequestHeader("u-projectId") Integer projectId, HttpServletRequest request) {
        operateMo.createBuild(User.class, projectId);
        Ro<User> ro = new Ro<>(RoState.FAIL);
        final Integer roleId0 = (int) request.getAttribute("roleId");
        Integer projectId1 = (Integer) operateMo.getEntity().get("projectId");
        if (Objects.isNull(projectId1)) {
            return ro.setMessage("超级管理员用户请传入参数[projectId]");
        }
        if (Objects.isNull(operateMo.getEntity().get("phone")) && Objects.isNull(operateMo.getEntity().get("userName"))) {
            ro.setMessage("账号(手机号/用户名)不能全部为空");
            return ro;
        }
        if (Objects.nonNull(operateMo.getEntity().get("phone"))) {
            String phone = (String) operateMo.getEntity().get("phone");
            if (!PhoneModel.isPhoneLegal(phone)) {
                return ro.setMessage("账号(手机号)格式错误");
            }
            QueryMo queryMo = new QueryMo();
            queryMo.put("phone", phone);
            queryMo.build(User.class, null);
            queryMo.getEqMap().remove("state");
            final User user = userService.selectUserByUserPhone((String) operateMo.getEntity().get("phone"));
            if (Objects.nonNull(user)) {
                if (roleId0.equals(Role.ROLE_SUPER_ADMIN.getValue())) {
                    return ro.setMessage("账号(手机号)已存在");
                } else if (roleId0.equals(Role.ROLE_COMPANY_ADMIN.getValue())) {
                    if (!projectId.equals(projectId1)) {
                        return ro.setMessage("账号(手机号)已存在");
                    } else {
                        if (user.getState().equals(0)) {
                            return ro.setMessage("账号(手机号)已存在");
                        } else if (user.getProjectId().equals(projectId1)) {
                            delete(user.getId());
                        }
                    }
                }
            }
        }
        if (Objects.nonNull(operateMo.getEntity().get("userName"))) {
            QueryMo queryMo = new QueryMo();
            queryMo.put("userName", operateMo.getEntity().get("userName"));
            queryMo.build(User.class, null);
            queryMo.getEqMap().remove("state");
            final User user = userService.selectUserByUsername((String) operateMo.getEntity().get("userName"));
            if (Objects.nonNull(user)) {
                if (roleId0.equals(Role.ROLE_SUPER_ADMIN.getValue())) {
                    return ro.setMessage("账号(用户名)已存在");
                } else if (roleId0.equals(Role.ROLE_COMPANY_ADMIN.getValue())) {
                    if (!projectId.equals(projectId1)) {
                        return ro.setMessage("账号(用户名)已存在");
                    } else {
                        if (user.getState().equals(0)) {
                            return ro.setMessage("账号(用户名)已存在");
                        } else if (user.getProjectId().equals(projectId1)) {
                            delete(user.getId());
                        }
                    }
                }
            }
        }
        if (Objects.isNull(operateMo.getEntity().get("password"))) {
            ro.setMessage("密码不能为空");
            return ro;
        } else {
            operateMo.getEntity().put("password", Base64.encode(String.valueOf(operateMo.getEntity().get("password"))));
        }
        if (Objects.nonNull(operateMo.getEntity().get("avatarUrl"))) {
            if (validateModel.uploadImageValidate(FileTypeEnum.FILE_USER_IMG.getValue(), operateMo.getEntity().get("avatarUrl").toString())) {
                return ro.setMessage("参数错误[avatarUrl],文件不存在或类别有误");
            }
        }
        Integer roleId = (Integer) operateMo.getEntity().get("roleId");
        if (Objects.nonNull(roleId)) {
            if (roleId0 >= roleId) {
                return ro.setMessage("注册用户者所注册的用户权限须低于本用户");
            } else if (roleId > 5) {
                return ro.setMessage("用户权限不存在");
            }
        } else {
            return ro.setMessage("未传入注册用户权限参数");
        }
        if (!userService.insert(operateMo)) {
            ro.setResultEnum(RoState.FAIL);
        }
        return ro.setResultEnum(RoState.SUCCESS);
    }

    @PatchMapping(value = "/modify")
    @Permission(value = 4, tags = Constants.API_PATROL)
    public Ro<User> modify(@RequestBody OperateMo operateMo, HttpServletRequest request,
                           @RequestHeader("u-uid") Integer userId, @RequestHeader("u-projectId") Integer projectId) {
        Ro<User> ro = new Ro<>();
        if (Objects.nonNull(operateMo.get("password"))) {
            operateMo.put("password", Base64.encode((String) operateMo.get("password")));
        }
        final ServiceRo serviceRo = operateMo.updateBuild(User.class, projectId);
        if (!serviceRo.getResult()) {
            return ro.setResultEnum(RoState.FAIL).setMessage(serviceRo.getMessage());
        }
        Integer paramRoleId = (Integer) operateMo.get("roleId");
        int roleId = (int) request.getAttribute("roleId");
        Integer id = (Integer) operateMo.get("id");
        if (Objects.isNull(id)) {
            return ro.setResultEnum(RoState.FAIL).setMessage("缺少[id]字段,请传参后重试");
        } else {
            if (roleId >= 3 && !userId.equals(id)) {
                return ro.setResultEnum(RoState.FAIL).setMessage("非管理员用户无法修改其他用户信息");
            }
        }
        Integer projectId1 = (Integer) operateMo.getEqMap().get("project_id");
        if (Objects.isNull(projectId1)) {
            return ro.setMessage("超级管理员用户请传入参数[projectId]");
        }
        if (roleId == 1) {
            operateMo.getEqMap().remove("project_id");
            operateMo.getEqMap().remove("state");
            operateMo.getEntity().put("projectId", projectId1);
            if (Objects.nonNull(operateMo.get("state"))) {
                operateMo.getEntity().put("state", operateMo.get("state"));
            }
        }
        if (operateMo.getEntity().size() == 0) {
            return ro.setResultEnum(RoState.FAIL).setMessage("无操作参数传入,请传参后重试");
        }
        if (Objects.nonNull(operateMo.get("userName"))) {
            if ("".equals(operateMo.get("userName"))) {
                operateMo.getEntity().remove("userName");
            } else {
                QueryMo queryMo = new QueryMo();
                queryMo.put("userName", operateMo.get("userName"));
                queryMo.build(User.class, null);
                queryMo.getEqMap().remove("state");
                User user = userService.selectOne(queryMo);
                if (Objects.nonNull(user)) {
                    if (!user.getId().equals(operateMo.get("id"))) {
                        return ro.setResultEnum(RoState.FAIL).setMessage("账号(用户名)已存在");
                    }
                }
            }
        }
        if (Objects.nonNull(operateMo.get("phone"))) {
            if ("".equals(operateMo.get("phone"))) {
                operateMo.getEntity().remove("phone");
            } else {
                String phone = (String) operateMo.get("phone");
                if (!PhoneModel.isPhoneLegal(phone)) {
                    return ro.setMessage("账号(手机号)格式错误");
                }
                QueryMo queryMo = new QueryMo();
                queryMo.put("phone", phone);
                queryMo.build(User.class, null);
                queryMo.getEqMap().remove("state");
                User user = userService.selectOne(queryMo);
                if (Objects.nonNull(user)) {
                    if (!user.getId().equals(operateMo.get("id"))) {
                        return ro.setResultEnum(RoState.FAIL).setMessage("账号(手机号)已存在");
                    }
                }
            }
        }
        if (Objects.nonNull(paramRoleId)) {
            if (paramRoleId > 5 || paramRoleId < 1) {
                return ro.setResultEnum(RoState.FAIL).setMessage("用户权限不存在");
            } else if (roleId <= 2 && userId.equals(id) && roleId == paramRoleId) {
                operateMo.getEntity().remove("roleId");
            } else if (roleId <= 2 && userId.equals(id)) {
                return ro.setResultEnum(RoState.FAIL).setMessage("管理员用户不能修改本人权限");
            } else if (roleId <= 2 && roleId >= paramRoleId) {
                return ro.setResultEnum(RoState.FAIL).setMessage("管理员用户所修改的其他用户权限须低于本用户");
            } else if (roleId >= 3 && roleId != paramRoleId) {
                return ro.setResultEnum(RoState.FAIL).setMessage("非管理员用户无法修改权限");
            }
        }
        if (Objects.nonNull(operateMo.get("avatarUrl"))) {
            if (validateModel.uploadImageValidate(FileTypeEnum.FILE_USER_IMG.getValue(), operateMo.get("avatarUrl").toString())) {
                return ro.setResultEnum(RoState.FAIL).setMessage("参数错误[avatarUrl],文件不存在或类别有误");
            }
        }
        if (!userService.update(operateMo)) {
            ro.setResultEnum(RoState.FAIL).setMessage("参数无匹配,修改失败");
        }
        return ro;
    }

    @DeleteMapping(value = "/delete/logical/{id}")
    @Permission(value = 3, tags = Constants.API_COMPANY)
    public Ro<User> logicallyDelete(@PathVariable Integer id, @RequestHeader("u-projectId") Integer projectId) {
        Ro<User> ro = new Ro<>();
        QueryMo queryMo = new QueryMo();
        queryMo.put("id", id);
        queryMo.build(User.class, projectId);
        if (!userService.logicallyDelete(queryMo)) {
            ro.setResultEnum(RoState.FAIL).setMessage("无匹配ID,删除失败");
        }
        return ro;
    }

    @GetMapping(value = "/list")
    @Permission(value = 2, tags = Constants.API_ADMIN)
    public Ro<IPage<User>> getAdminPageList(@RequestHeader("u-projectId") Integer projectId, @RequestHeader("u-uid") Integer userId,
                                            HttpServletRequest request) {
        QueryMo queryMo = QueryMo.getQueryMo(request);
        Ro<IPage<User>> ro = new Ro<>();
        queryMo.put("searchUserId", userId);
        queryMo.build(User.class, projectId);
        queryMo.put("roleId", request.getAttribute("roleId"));
        if (projectId == 1) {
            if (Objects.nonNull(queryMo.get("state"))) {
                queryMo.getEqMap().put("state", queryMo.get("state"));
            } else {
                queryMo.getEqMap().remove("state");
            }
        }
        return ro.setContent(userService.searchListPage(queryMo));
    }

    @GetMapping(value = "/{id}")
    @Permission(value = 2, tags = Constants.API_ADMIN)
    public Ro<User> getOne(@PathVariable Integer id,
                           @RequestHeader("u-projectId") Integer projectId,
                           HttpServletRequest request) {
        Ro<User> ro = new Ro<>();
        if (Objects.isNull(id)) {
            return ro.setResultEnum(RoState.PARAMS_MISS_ERROR);
        }
        QueryMo queryMo = new QueryMo();
        queryMo.put("id", id);
        queryMo.build(User.class, projectId);
        queryMo.put("roleId", request.getAttribute("roleId"));
        queryMo.getEqMap().remove("state");
        User user = userService.selectOne(queryMo);
        if (Objects.isNull(user)) {
            ro.setMessage("未查询到数据");
        } else {
            ro.setContent(user);
        }
        return ro;
    }

    @DeleteMapping(value = "/admin/delete/{id}")
    @Permission(value = 1, tags = Constants.API_ADMIN)
    public Ro<User> delete(@PathVariable Integer id) {
        Ro<User> ro = new Ro<>();
        QueryMo queryMo = new QueryMo();
        queryMo.put("id", id);
        queryMo.build(User.class, null);
        queryMo.getEqMap().remove("state");
        if (!userService.delete(queryMo)) {
            ro.setResultEnum(RoState.FAIL).setMessage("无匹配ID,删除失败");
        }
        return ro;
    }
}
